<?php
/**
 * Created by 784855684@qq.com.
 * User: linzh
 * Date: 8/22/17
 * Time: 8:32 PM
 */


namespace inframe\core\session;

use inframe\core\cache\Memcached;

/**
 * Class Handler 自定义Session处理器
 * @package inframe\core\session
 */
class Handler implements \SessionHandlerInterface
{
    /**
     * 驱动
     * @var Memcached
     */
    private $adapter = null;
    /**
     * session生命周期
     * @var int
     */
    private $lifetime = 0;

    public function __construct($lifetime = 1440)
    {
        $this->lifetime = (int)$lifetime;
        $this->adapter = Memcached::getInstance();
    }

    /**
     * Close the session
     * Closes the current session. This function is automatically executed when closing the session, or explicitly via session_write_close().
     * This method should release the exclusive lock that was acquired by the open() method.
     * Note that this will effectively serialize parallel requests, which affects performance for a single user session.
     * Not locking the resource would on the other hand allow for race conditions if two or more parallel requests change the session data.
     * @return int 会话存储的返回值（通常成功返回 0，失败返回 1）。
     */
    public function close()
    {
        return true;
    }

    /**
     * Destroy a session
     * @param string $session_id The session ID being destroyed.
     * @return int 会话存储的返回值（通常成功返回 0，失败返回 1）。
     */
    public function destroy($session_id)
    {
        return $this->adapter->clean($session_id) ? true : false;
    }

    /**
     * Cleanup old sessions
     * 为了清理会话中的旧数据，PHP 会不时的调用垃圾收集回调函数
     * session数据的声明周期由memcached设置时决定
     * @param int $maxlifetime
     * @return int 会话存储的返回值（通常成功返回 0，失败返回 1）。
     */
    public function gc($maxlifetime)
    {
        return true;
    }

    public function open($save_path, $name)
    {
        return true;
    }

    /**
     * 如果会话中有数据，read 回调函数必须返回将会话数据编码（序列化）后的字符串。 如果会话中没有数据，read 回调函数返回空字符串。
     * @param string $session_id
     * @return string
     */
    public function read($session_id)
    {
        if ($data = $this->adapter->get($session_id, null)) {
            $this->adapter->touch($session_id, $this->lifetime);
            return $data;
        }
        return '';
    }

    public function write($session_id, $session_data)
    {
        return $this->adapter->set($session_id, $session_data, $this->lifetime) ? true : false;
    }

}